package com.hxzy.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hxzy.common.enums.AckCode;
import com.hxzy.common.exception.ServiceException;
import com.hxzy.common.util.JwtTokenService;
import com.hxzy.common.util.PasswordLockUtil;
import com.hxzy.controller.vue.employee.req.EmployeeReq;
import com.hxzy.controller.vue.employee.resp.EmployeeResp;
import com.hxzy.controller.vue.login.req.AdminLoginReq;
import com.hxzy.controller.vue.login.resp.AdminLoginResp;
import com.hxzy.entity.Employee;
import com.hxzy.service.EmployeeService;
import com.hxzy.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
* @author 11452
* @description 针对表【employee(后台管理员表)】的数据库操作Service实现
* @createDate 2023-08-28 11:54:55
*/
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee>
    implements EmployeeService{
    /**
     * 密码输入错误锁定功能
     */
    @Autowired
    private PasswordLockUtil  passwordLockUtil;



    @Override
    public AdminLoginResp login(AdminLoginReq req) {
       //select id,login_name,login_pwd, status,avatar from employee where login_name=?
        // where 通过 Lambda 表达式，方便的编写各类查询条件，无需再担心字段写错
        LambdaQueryWrapper<Employee> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Employee::getLoginName, req.getAccount());
        //select id,login_name,login_pwd, status,avatar
        queryWrapper.select(Employee::getId,Employee::getLoginName,Employee::getLoginPwd,Employee::getStatus,Employee::getAvatar,Employee::getRoot);

        Employee employee = super.baseMapper.selectOne(queryWrapper);

        if(Objects.isNull(employee)){
            throw new ServiceException(AckCode.LOGIN_ACCOUNT_PASSWORD_ERROR);
        }

        String uniqueValue= JwtTokenService.ADMIN+"-"+ employee.getId();

        boolean pwdSuccess= BCrypt.checkpw(req.getPassword(), employee.getLoginPwd());

            //如果启动密码错误服务
        if(this.passwordLockUtil.isPasswordLock()){
            if(!this.passwordLockUtil.isAccountLocked(uniqueValue)){
                //密码错误
                if(!pwdSuccess){
                    //把密码错误次数更新,如果超过3次，一定抛出异常,如果没有超过就不会抛出异常
                    this.passwordLockUtil.logFailedLoginAttempt(uniqueValue);
                }
            }
            //如果密码正确的，就要删除redisKey
            this.passwordLockUtil.unlockAccount(uniqueValue);

        }else {
           //没有开启密码锁的服务
            if(!pwdSuccess) {
                throw new ServiceException(AckCode.LOGIN_ACCOUNT_PASSWORD_ERROR);
            }
        }

        if(employee.getStatus().equals("1")){
            throw new ServiceException(AckCode.DEVICE_BANNED);
        }
        //转换对象
        AdminLoginResp  loginResp=new AdminLoginResp();
        loginResp.setId(employee.getId());
        loginResp.setName(employee.getLoginName());
        loginResp.setPermissions(Arrays.asList("admin"));
        loginResp.setAvatar(employee.getAvatar());
        loginResp.setRoot(employee.getRoot());
        return loginResp;
    }

    /**
     * 分页查询
     * @param req
     * @return
     */
    @Override
    public PageInfo<EmployeeResp> search(EmployeeReq req) {

        return PageHelper.startPage(req.getPage(),req.getSize())
                .doSelectPageInfo(()->{
                    List<EmployeeResp> resp=this.baseMapper.search(req);

                });
    }

    @Override
    public boolean existsValue(SFunction<Employee,?> column, String value,Object primaryKeyValue) {
        LambdaQueryWrapper<Employee> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(column,value);
        //主键有值
        if(Objects.nonNull(primaryKeyValue)){
            queryWrapper.ne(Employee::getId, primaryKeyValue);
        }
        Long count = this.baseMapper.selectCount(queryWrapper);
        return count>0;
    }

    @Override
    public boolean changePassword(Long id, String password) {
        return this.baseMapper.changePwd(id, BCrypt.hashpw(password))>0;
    }

    /**
     * excel下载
     * @param req
     * @return
     */
    @Override
    public List<Employee> excelDownload(EmployeeReq req) {
        LambdaQueryWrapper<Employee> queryWrapper=new LambdaQueryWrapper<>();
        if(StrUtil.isNotBlank(req.getLoginName())){
            queryWrapper.like(Employee::getLoginName, req.getLoginName());
        }
        return super.baseMapper.selectList(queryWrapper);
    }
}




